#! /bin/sh

set -e
. /usr/share/debconf/confmodule
#set -x

log() {
	logger -t cdrom-detect "$@"
}

fail () {
	log "CDROM-detect failed; unmounting CD just to be sure"
	umount /cdrom 2>/dev/null || true
	exit 1
}

# Is a cdrom already mounted?  If so, assume it's the right one..
mount | grep -q 'on /cdrom' && exit 0
if [ -e /cdrom/.disk/info ]; then
	CDNAME=`cat /cdrom/.disk/info`
	log "Detected CD '$CDNAME'"
	# This produces /var/log/installer/media-info on the installed
	# system.
	printf %s "$CDNAME" >/var/log/media-info
	exit 0
fi

hw-detect cdrom-detect/detect_progress_title || true

log "Searching for Ubuntu installation media..."

mkdir /cdrom 2>/dev/null || true

while true
do
	mounted=

	if db_get cdrom-detect/try-usb && [ "$RET" = true ]; then
		devices="$(list-devices usb-partition)"
		devices="$devices $(list-devices mmc-partition)"
		for device in $devices; do
			if mount -t vfat -o ro,exec $device /cdrom &&
			   [ -e /cdrom/.disk/info ]; then
				log "CD-ROM mount succeeded: device=$device fstype=vfat"
				mounted=1
				db_set cdrom-detect/cdrom_device $device
				db_set cdrom-detect/cdrom_fs vfat
				break
			else
				log "CD-ROM mount failed: device=$device fstype=vfat"
				umount /cdrom 2>/dev/null || true
			fi
		done
	fi

	if [ "$mounted" ]; then
		break
	fi

	wrong=0
	devices="$(list-devices cd; list-devices maybe-usb-floppy)"
	sleep 20
	devices="$(list-devices cd; list-devices maybe-usb-floppy)"
	for device in $devices; do
		if mount -t iso9660 -o ro,exec $device /cdrom; then
			log "CD-ROM mount succeeded: device=$device fstype=iso9660"
			if [ -e /cdrom/.disk/info ]; then
				CDNAME=`cat /cdrom/.disk/info`
				log "Detected CD '$CDNAME'"
				mounted=1
				db_set cdrom-detect/cdrom_device $device
				db_set cdrom-detect/cdrom_fs iso9660
				break
			else
				log "The CD on $device is not an Ubuntu CD!"
				wrong=1
				umount /cdrom 2>/dev/null || true
			fi
		else
			log "CD-ROM mount failed: device=$device fstype=iso9660"
		fi
	done
	
	if [ "$mounted" = "1" ]; then
		break
	fi

	if [ "$wrong" = "1" ]; then
		db_input critical cdrom-detect/wrong-cd || [ $? -eq 30 ]
		db_go
		fail
	fi

	# If a device was detected but the mount failed, ask for the CD.
	if [ -n "$devices" ]; then
		db_input critical cdrom-detect/retry || [ $? -eq 30 ]
		db_go
		db_get cdrom-detect/retry
		if [ "$RET" = "true" ]; then
			log "Unmounting CD just to be sure"
			umount /cdrom 2>/dev/null || true
			continue
		else
			fail
		fi
	fi
 
	# If no device was detected, perhaps a driver floppy is needed.
	if [ -e /usr/lib/debian-installer/retriever/media-retriever ]; then
		db_input critical cdrom-detect/load_media
		db_go
		db_get cdrom-detect/load_media
		if [ "$RET" = true ]; then
			anna media-retriever
			hw-detect cdrom-detect/detect_progress_title || true
			continue
		fi
	fi

	# Otherwise manual configuration may be needed
	db_input critical cdrom-detect/manual_config || [ $? -eq 30 ]
	db_go
	db_get cdrom-detect/manual_config

	modules=none
	for i in `ls -1 /lib/modules/*/kernel/drivers/cdrom/ | sed 's/\.ko$//' | sed 's/\.o$//'`; do
		modules="$modules, $i"
	done
    
	if [ "$RET" = true ]; then
		db_subst cdrom-detect/cdrom_module choices "$modules"
		db_input critical cdrom-detect/cdrom_module || [ $? -eq 30 ]
		db_go

		db_get cdrom-detect/cdrom_module
		module="$RET"

		db_input critical cdrom-detect/cdrom_device || [ $? -eq 30 ]
		db_go

		db_get cdrom-detect/cdrom_device
		device="$RET"

		if [ "$module" != none ]; then
			modprobe $module
		fi

		if mount -t iso9660 -o ro,exec $device /cdrom; then
			log "CD-ROM mount succeeded: device=$device fstype=iso9660"
			db_set cdrom-detect/cdrom_fs iso9660
			mounted=1
			db_set cdrom-detect/cdrom_fs iso9660
			break
		else
			log "CD-ROM mount failed: device=$device fstype=iso9660"
			fail
		fi
	else
		fail
	fi
done

if [ -e /cdrom/.disk/info ]; then
	CDNAME=`cat /cdrom/.disk/info`
	log "Detected CD '$CDNAME'"
else
	log "The available CD is not an Ubuntu CD!"
	db_input critical cdrom-detect/wrong-cd || [ $? -eq 30 ]
	db_go
	fail 
fi

db_get cdrom-detect/cdrom_device
device="$RET"

ARCH="`udpkg --print-architecture`"
if [ "$ARCH" = i386 ]; then
    db_input low cdrom-detect/cdrom_hdparm || [ $? -eq 30 ]
    db_go
    db_get cdrom-detect/cdrom_hdparm
    params="`printf '%s' "$RET" | sed 's/^ *//'`"

    if [ "$device" ] && [ "$params" ]; then
	hdparm $params "$device"
	apt-install hdparm || true
    fi
fi

# Get all the pool directories into the dentry cache, to cut down on seek
# times.
poolcount="$(set -- /cdrom/pool/*/*; echo $#)"
db_progress START 0 "$poolcount" cdrom-detect/scanning_progress_title
for pooldir in /cdrom/pool/*/*; do
	if [ -d "$pooldir" ]; then
		db_subst cdrom-detect/scanning_progress_step DIR "$pooldir"
		db_progress INFO cdrom-detect/scanning_progress_step
		log-output --pass-stdout -t cdrom-detect find "$pooldir/" >/dev/null || true
	fi
	db_progress STEP 1
done
db_progress STOP

# Set the suite and codename used by base-installer and base-config
# to the suite/codename that is on the CD. In case there are multiple
# suites, prefer the one in default-release.
for dir in $(cat /etc/default-release) $(ls -1 /cdrom/dists/); do
	relfile="/cdrom/dists/$dir/Release"
	if [ -e $relfile ]; then
		suite=$(sed -n 's/^Suite: *//p' "$relfile")
		codename=$(sed -n 's/^Codename: *//p' "$relfile")
		log "Detected CD with '$suite' ($codename) distribution"
		db_set cdrom/suite "$suite"
		db_set cdrom/codename "$codename"

		break
	fi
done

if [ -z "$suite" ]; then
	log "Error reading Release file; unable to determine distribution"
	db_input critical cdrom-detect/no-release || [ $? -eq 30 ]
	db_go
	fail
fi

# Install eject-udeb, to be able to use it in the finish-install script.
anna-install eject-udeb || true

# This produces /var/log/installer/media-info on the installed system.
printf %s "$CDNAME" >/var/log/media-info

# Hey, we're done
db_subst cdrom-detect/success cdname "$CDNAME"
db_input low cdrom-detect/success || [ $? -eq 30 ]
db_go

anna-install apt-mirror-setup || true
if [ ! -e /cdrom/.disk/base_installable ]; then
	log "Base system not installable from CD, requesting choose-mirror"
	anna-install choose-mirror || true
else
	anna-install apt-cdrom-setup || true

	# Install <codename>-support udeb (if available).
	db_get cdrom/codename
	anna-install $RET-support || true
fi

exit 0
